package org.pliers.feign;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.IOException;

import org.pliers.Mappers;
import org.pliers.exception.BaseException;
import org.pliers.exception.BusinessException;
import org.pliers.web.HttpErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import feign.Response;
import feign.Util;
import feign.codec.ErrorDecoder;

@Configuration
public class FeignErrorDecoder implements  ErrorDecoder{
    private static final Logger log = LoggerFactory.getLogger(FeignErrorDecoder.class);

    private ErrorDecoder delegate = new Default();
    
    @Override
    public Exception decode(String methodKey, Response response) { 
        log.warn("FeignErrorDecoder receive message. method : {} , ",methodKey);
        log.warn("FeignErrorDecoder receive message. response status : {} ",response.status());
        byte[] responseBody;
        String body = "" ;
        try {
        	if(response.body() != null) {
        		responseBody = Util.toByteArray(response.body().asInputStream());
                body = new String(responseBody,UTF_8);
        	}
        } catch (IOException e) {
            return new RuntimeException("Failed to process response body.", e);
        }
        log.warn("FeignErrorDecoder receive message. response body : {} ", body );
        try {
            log.warn("================1=================");
        	String json = body;
             if (response.status() == HttpErrorCode.BUSINESSEXCEPTION_HTTPSTATUS.code) {
                 log.warn("================2=================");
            	return buildException(json, methodKey, BusinessException.class);
            }
        }
        catch(IOException jp) {
            return new RuntimeException("Failed to convert body str to exception object  .", jp);
        }

        return delegate.decode( methodKey,  response);
    }
    
    private Exception buildException(String json, String methodKey, Class<? extends BaseException> exClass ) throws IOException {
        log.warn("================3=================");
        BaseException ex = Mappers.objectMapper.readValue(json, exClass);
        log.warn("================4=================");
    	if (ex.getData() == null) ex.setData(methodKey);
    	return ex ;
    }

}
